AWS Lambda の Custom Runtimes を利用して Elixir で作られた Lambda + API Gateway を実行してみる #reinvent
この記事は AWS Lambda Custom Runtimes芸人 Advent Calendar 2018 の 21日目 です。
はじめに
keynoteの二日目で AWS Lambda でカスタムランタイムが利用できる発表があり、 AWS Lambda での言語選択の幅に選択肢が増えたことで、多くのアプリケーション開発者を熱狂させました。
【アップデート】 もう言語で悩まない!AWS LambdaでCustom Runtimeが利用できるようになりました! #reinvent
早速ですが、 Alert Logic から Erlang と Elixir の AWS Lambda についての記事が上がってました。
ErlangとElixirは、多くの開発者に人気のある言語ですが、これまでAWS Lambdaではサポートされていませんでした。 これらの言語は、独自の賛否両論があります。 Alert Logic は、 Erlang ネイティブランタイムと rebar3 を使用したビルドとパッケージングの統合サポート、およびElixirネイティブランタイムによるAWS Lambda機能のサポート、およびMixを使用した統合ビルド/パッケージサポートのサポートを含むAWSラムダ機能のサポートをリリースしました。
Erlang が動作するところは以前、 Erlangを動かしてみたブログ の方で挑戦したのですが、今回は Elixir で作成された Lambda をAPI経由で実行するところまでやってみたいと思います。
AWS Lambda で Elixir を実行
AWS Lambda のカスタムランタイムとして、 aws-lambda-elixir-runtime を使用することで、 Elixir を AWS Lambda で実行させることができます。
せっかくなのでHello World的な簡易プログラムではなく、 API Gateway + Lambda + DynamoDB のオーソドックスなサーバーレスアプリケーション構成を試して見たいと思います。
構成は ErllambdaElixirExample という、サンプル実装が提供されていますので、こちらを使ってみました。
$ git clone https://github.com/alertlogic/erllambda_elixir_example.git $ cd erllambda_elixir_example
Elixir build用のdocker imageを取得
ビルド用の docker image、 alertlogic/erllambda が提供されていますので、こちらを使用します。
Elixir の動作環境については、別途タグが打たれたものを利用します。
2018/12/20時点では、 20.3-elixir
のタグが追加されていました。
$ docker pull alertlogic/erllambda:20.3-elixir
プロジェクトのビルド
以下の mix deps.get
コマンドで依存するファイルを取得します。
$ docker run -it --rm -v `pwd`:/buildroot -w /buildroot -e MIX_ENV=prod alertlogic/erllambda:20.3-elixir mix deps.get
最後に mix erllambda.release
コマンドを実行すれば、 Lambda にアップロードできる形式のバイナリが出力されます。
$ docker run -it --rm -v `pwd`:/buildroot -w /buildroot -e MIX_ENV=prod alertlogic/erllambda:20.3-elixir mix erllambda.release
バイナリは、 _build
の下位のフォルダに配置されます。
_build/prod/rel/erllambda_elixir_example/releases/0.1.0/erllambda_elixir_example.zip
AWS Lambda のデプロイ
CloudFormation テンプレートでのデプロイ方法が提供されていますので、こちらのコマンドでデプロイします。
CloudFormation テンプレート用の S3 バケットを作成しておきます。
バケット名の erllambda-elixir-example
の部分は任意の名前で構いません。
$ aws s3api create-bucket --bucket erllambda-elixir-example
CloudFormation のパッケージをアップロードするコマンドを実行します
$ aws cloudformation package \ --template-file etc/template.yaml \ --output-template-file packaged.yaml \ --s3-bucket erllambda-elixir-example
パッケージをアップロードした後に CloudFormation のデプロイコマンドを実行します。
$ aws cloudformation deploy --capabilities CAPABILITY_IAM \ --template-file packaged.yaml \ --stack-name erllambda-elixir-example
コマンドを実行すると、ランタイムに 「独自のランタイム」 が指定された AWS Lambda がデプロイされます。
Amazon API Gateway の方にもリソースが作成されました。
AWS Lambda の実行
curlでPOSTコマンドを叩いて見ましょう。API経由でパラメータに指定された値を元に、DynamoDBへの書き込みが実施されます。
$ curl -X POST https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/MyResource?id=0001&message=test
動きました!DynamoDBのテーブルに指定された値が入力されています。
まとめ
カスタムランタイムは用途が限定的ではありますが、標準で提供されている言語では対応しきれない処理を一つの Lambda で捌く要件が出た際に、活躍の場が出てくるのかもしれないですね。(その時は Lambda 以外を検討したほうがいいのかもしれませんが...)